﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Revis.VClinicNet.App.Internal.Dto;
using Revis.VClinicNet.App.Internal;
using Revis.VClinicNet.UI.Internal.Mvc.Models.Forms;
using Revis.VClinicNet.UI.Internal.Mvc.Models;
using Revis.VClinicNet.App.Internal.Dto.Validation;
using Revis.VClinicNet.UI.Internal.Mvc.Extensions;
using Revis.VClinicNet.Core.Domain.Credentials;
using Revis.VClinicNet.UI.Internal.Mvc.Infrastructure;

namespace Revis.VClinicNet.UI.Internal.Mvc.Controllers
{
    public class VisitController : Infrastructure.ControllerBase
    {
        //
        // GET: /Visit/

        private IDoctorService _doctorService = null;
        private IVisitService _visitService = null;

        public VisitController(IDoctorService ids, IVisitService ivs) :
            base("Visit")
        {
            _doctorService = ids;
            _visitService = ivs;
        }

        /// <summary>
        /// Show empty create visit form
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Recepcionist | WorkerUserRole.Administrator | WorkerUserRole.Doctor)]
        public ActionResult Create()
        {
            IList<DoctorInfoDto> doctors = _doctorService.ListAllActive();
            VisitCreateFormModel formModel = new VisitCreateFormModel(doctors, DateTime.Now);
            return View(formModel);
        }

        /// <summary>
        /// Send filled visit create model to core and shoe errors if necessary
        /// </summary>
        /// <param name="model">patient create model</param>
        /// <returns></returns>
        [HttpPost]
        [HistoryBackLinked(Type = BackLinkType.ModifyForm)]
        [AuthorizeFor(Role =
            WorkerUserRole.Recepcionist | WorkerUserRole.Administrator | WorkerUserRole.Doctor)]
        public ActionResult Create(VisitCreateModel model)
        {
            if (ModelState.IsValid) {
                try {
                    DateTime date = model.Date;
                    long id = _visitService.Create(new VisitCreateDto() {
                        DoctorId = model.DoctorId,
                        PatientId = model.PatientId,
                        Date = date,
                    });
                    return RedirectToAction("Detail", new { id = id });
                } catch (ValidationException ve) {
                    ModelState.AddModelErrors(ve);
                } catch (ClinicException ce) {
                    ModelState.AddErrorMessage(ce.Message);
                }
            }
            return View(new VisitCreateFormModel(model, _doctorService.ListAllActive()));
        }

        /// <summary>
        /// Visit detail view action
        /// </summary>
        /// <param name="id">visit id</param>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Administrator | WorkerUserRole.Recepcionist | WorkerUserRole.Doctor)]
        public ActionResult Detail(long id)
        {
            VisitDto visit = _visitService.Find<VisitDto>(id);
            if (visit == null) {
                return ErrorView("Nie znaleziono wizyty", "Detail");
            }
            return View(visit);
        }

        /// <summary>
        /// Action to display today logged doctor visits
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Doctor)]
        public ActionResult Today()
        {
            IList<VisitInfoDto> visitsInfos = _doctorService.TodayVisits(this.UserId);
            return View(visitsInfos);
        }

        /// <summary>
        /// Action to display all logged doctor visits
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Doctor)]
        public ActionResult AllD()
        {
            IList<VisitInfoDto> visitsInfos = _visitService.ListAllByDoctor(this.UserId);
            return View(visitsInfos);
        }

        /// <summary>
        /// Action to display all visits by doctor owner id
        /// </summary>
        /// <param name="id">doctor id</param>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Administrator)]
        public ActionResult AllA(long id)
        {
            IList<VisitInfoDto> visitsInfos = _visitService.ListAllByDoctor(id);
            return View(visitsInfos);
        }

        /// <summary>
        /// Action to display all patient visits
        /// </summary>
        /// <param name="id">patient id</param>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Recepcionist | WorkerUserRole.Administrator)]
        public ActionResult Patient(long id)
        {
            IList<VisitInfoDto> visistsInfos = _visitService.ListAllByPatient(id);
            return View(visistsInfos);
        }

        /// <summary>
        /// Delete confirmation view
        /// </summary>
        /// <param name="id">visit id</param>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Doctor | WorkerUserRole.Administrator | WorkerUserRole.Recepcionist)]
        public ActionResult Delete(long id)
        {
            VisitInfoDto visit = _visitService.Find<VisitInfoDto>(id);
            if (visit == null) {
                return ErrorView("Nie znaleziono wizyty", "Detail");
            }
            return View(visit);
        }

        /// <summary>
        /// Action to delete visit
        /// </summary>
        /// <param name="id">visit id</param>
        /// <returns></returns>
        [HttpPost]
        [HistoryBackLinked(Type = BackLinkType.ModifyForm)]
        [AuthorizeFor(Role = WorkerUserRole.Doctor | WorkerUserRole.Administrator | WorkerUserRole.Recepcionist)]
        public ActionResult DeleteVisit(long id)
        {
            try {
                _visitService.Delete(id);
            } catch (ClinicException ce) {
                return View("Error", new HandleErrorInfo(ce, "Visit", "DeleteVisit"));
            }
            return Redirect(this.BackLinkUrl());
        }
    }
}
